//--------------------------------------------------------------------------------------
// File: Tutorial06.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------


//--------------------------------------------------------------------------------------
// Texture samplers
//--------------------------------------------------------------------------------------
Texture2D Skyglow			: register(t0); 
Texture2D Skycolor			: register(t1); 
Texture2D Sun				: register(t2); 
Texture2D Star				: register(t3); 

SamplerState SamplerLinearClamp
{
    Filter = MIN_MAG_MIP_LINEAR;
};

//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
shared cbuffer cbVSPF : register(cb0)  // VS PER FRAME
{
	float4x4	View;
	float4x4	ViewProjection;			// View * Projection matrix
	float4		g_LightDiffuse;         // Light's diffuse color  
	float4		g_vEye; 

	float		g_FogStart;
	float		g_FogEnd;

	float		g_fTime; 
};

shared cbuffer cbPSPF : register(cb0) // PS PER FRAME
{
	float4		SunPos;						 // <-- SET
};

shared cbuffer cbVSPO : register(cb1) // VS PER OBJECT
{      
	float4x4	World;					// <-- SET // World matrix for object
	float4		g_lGloballight;
};

shared cbuffer cbPSPO : register(cb1) // PS PER OBJECT
{

};
//--------------------------------------------------------------------------------------
struct VS_INPUT
{
    float4 Pos : POSITION;
};

struct VST_INPUT
{
    float4 Pos : POSITION;
	float2 Tex : TEXCOORD0;
};

struct VStar_INPUT
{
    float4   Pos		: POSITION;
	float2   Tex		: TEXCOORD0;
	matrix   Instance	: INSTANCE0;
};

struct PS_INPUT
{
    float4 Pos : SV_POSITION;
};

struct PST_INPUT
{
    float4 Pos		: SV_POSITION;
	float2 Tex		: TEXCOORD0;
	float3 Vertex	: TEXCOORD1;
};

struct PSky_INPUT
{
    float4 Pos		: SV_POSITION;
	float3 Vertex	: TEXCOORD0;
};

//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT VS( VS_INPUT input )
{
    PS_INPUT output = (PS_INPUT)0;
    output.Pos = mul( input.Pos, World );
  //  output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, ViewProjection );
    
    return output;
}

PSky_INPUT VSky( VS_INPUT input )
{
    PSky_INPUT output = (PSky_INPUT)0;

    output.Pos = mul( input.Pos, ViewProjection );

	output.Vertex = input.Pos.xyz;
    
    return output;
}

PST_INPUT VST( VST_INPUT input )
{
    PST_INPUT output = (PST_INPUT)0;
    output.Pos		= mul( input.Pos, World );
	output.Vertex	= output.Pos.xyz;

    output.Pos		= mul( output.Pos, ViewProjection );
    
	output.Tex		= input.Tex;

    return output;
}

PST_INPUT VStar( VStar_INPUT input )
{
    PST_INPUT output = (PST_INPUT)0;
	output.Pos = mul( input.Pos, input.Instance );
    output.Pos = mul( output.Pos, World );
  //  output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, ViewProjection );
    
	output.Tex = input.Tex;
	output.Vertex = input.Pos.xyz;

    return output;
}


//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( PS_INPUT input) : SV_Target
{
    float4 finalColor = 0;
    finalColor.a = 1;
	
    return finalColor;
}

float4 PStar( PST_INPUT input) : SV_Target
{
    float4 finalColor = Star.Sample(SamplerLinearClamp, input.Tex );
    return finalColor;
}

float4 PST( PST_INPUT input) : SV_Target
{
    float4 finalColor = 0;
		
	float3 norm		= normalize(input.Vertex);
	float3 sun		= SunPos.xyz;
	float SunDot	= dot(sun, norm);

	/*
    float4 Kc =  Sun.Sample(SamplerLinearClamp, input.Tex );
	float4 Kg =  Skyglow.Sample(SamplerLinearClamp, float2((sun.y + 1.0) / 2.0, norm.y  ));
	*/
	finalColor = Sun.Sample(SamplerLinearClamp, input.Tex );
	if (SunDot < -0.99) {
		finalColor = float4(finalColor.rgb / 750.0, finalColor.a);
	} else {
		finalColor.rg *= 1.0 + (SunDot + 1.0) * 20.0;
	}
    return finalColor;
}

float4 PSky( PSky_INPUT input) : SV_Target
{
    float4 finalColor = 0;

	float3 norm		= normalize(input.Vertex);
	float3 sun		= SunPos.xyz;
	float SunDot	= dot(sun, norm);
	//float2 cycle	= {fmod(SunPos.w, 100.0), 0};

	float4 Kc = Skycolor.Sample(SamplerLinearClamp, float2((sun.y + 1.0) / 2.0, SunDot ));
	float4 Kg =  Skyglow.Sample(SamplerLinearClamp, float2((sun.y + 1.0) / 2.0, norm.y  ));


	finalColor = float4(Kc.rgb + Kg.rgb * Kg.a / 2.0, Kc.a);

    return finalColor;
}

DepthStencilState DisableDepth
{
    DepthEnable = FALSE;
};

DepthStencilState EnableDepth
{
    DepthEnable = TRUE;
};

BlendState NoAlphaBlend
{
    BlendEnable[0] = FALSE;

    SrcBlend = SRC_ALPHA;
    DestBlend = INV_SRC_ALPHA;
};

BlendState AlphaBlend
{
    BlendEnable[0] = TRUE;

    SrcBlend = SRC_ALPHA;
    DestBlend = INV_SRC_ALPHA;
};

technique11 Render
{
    pass p0
    {
        SetVertexShader(CompileShader(vs_4_0, VS()));
        SetHullShader(NULL);
        SetDomainShader(NULL);
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0, PS()));
    }
};

technique11 RenderSky
{
    pass p0
    {
        SetVertexShader(CompileShader(vs_4_0, VSky()));
        SetHullShader(NULL);
        SetDomainShader(NULL);
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0, PSky()));

		SetDepthStencilState(DisableDepth, 0);
		SetBlendState( AlphaBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    }
    pass p1
    {
        SetVertexShader(NULL);
        SetHullShader(NULL);
        SetDomainShader(NULL);
        SetGeometryShader(NULL);
        SetPixelShader(NULL);

		SetDepthStencilState(EnableDepth, 0);
		SetBlendState( NoAlphaBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    }
};

technique11 RenderSun
{
    pass p0
    {
        SetVertexShader(CompileShader(vs_4_0, VST()));
        SetHullShader(NULL);
        SetDomainShader(NULL);
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0, PST()));
    }
};

technique11 RenderStar
{
    pass p0
    {
        SetVertexShader(CompileShader(vs_4_0, VStar()));
        SetHullShader(NULL);
        SetDomainShader(NULL);
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0, PStar()));

		SetDepthStencilState(DisableDepth, 0);
		SetBlendState( AlphaBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    }
};